package com.sniper;

import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.util.List;
import java.util.Properties;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.DOMReader;
import org.w3c.tidy.Tidy;

public class SniperMain {
    private String username; 
    private String password;
        
    private String departure;
    private String destination;
    private String date;
    
    private HttpClient httpClient;
    private Tidy tidy;
    
    public static void main(String[] args) throws Exception {
        new SniperMain().run();
    }
    
    public SniperMain() throws Exception {
    	Properties props = new Properties();    	
    	props.load(new InputStreamReader(new FileInputStream("sniper.conf"), "UTF-8"));
    	
    	username = props.getProperty("sniper.username");
    	password = props.getProperty("sniper.password");
    	
    	departure = URLEncoder.encode(props.getProperty("sniper.departure"),"UTF-8");
        destination = URLEncoder.encode(props.getProperty("sniper.destination"),"UTF-8");
        date = props.getProperty("sniper.date");
    }
    
    public void run() throws Exception {               
        httpClient = new HttpClient();
        
        tidy = new Tidy();
        tidy.setXHTML(false);
        tidy.setInputEncoding("UTF-8");
        tidy.setQuiet(true);
        tidy.setShowWarnings(false);
        tidy.setShowErrors(0);
        
        String homePageUrl = login();
        String planPageUrl = selectPlanPage(homePageUrl);
        getResults(planPageUrl);
    }
    
    // Логін на портал
    private String login() throws Exception {
        GetMethod loginPage = new GetMethod("http://www.e-kvytok.com.ua/wps/portal");
        httpClient.executeMethod(loginPage);
        
        Document doc = new DOMReader().read(tidy.parseDOM(loginPage.getResponseBodyAsStream(), null));
        
        Element loginForm = (Element) doc.selectSingleNode("//form[@name=\"LoginForm\"]");
        String loginPostUrl = loginForm.attribute("action").getValue();
        
        PostMethod loginPostMethod = new PostMethod("http://www.e-kvytok.com.ua" + loginPostUrl);

        loginPostMethod.setParameter("wps.portlets.userid", username);
        loginPostMethod.setParameter("password", password);

        httpClient.executeMethod(loginPostMethod);
        
        String homePageUrl = loginPostMethod.getResponseHeader("Location").getValue();
        
        return homePageUrl;
    }

    // До "Планування поїздки"
    private String selectPlanPage(String homePageUrl) throws Exception {
        GetMethod homePage = new GetMethod(homePageUrl);
        httpClient.executeMethod(homePage);
        
        Document homePageDocument = new DOMReader().read(tidy.parseDOM(homePage.getResponseBodyAsStream(), null));
        
        Element planLink = (Element) homePageDocument.selectSingleNode("//div[@id='wptheme-topnav']/ul/li[2]/a");       
        return planLink.attribute("href").getValue();
    }

    // actionurl на "плануванні поїздки", змінюється при заповненні даних
    private String clickOnFormUrl;
    
    @SuppressWarnings("unchecked")
    private void getResults(String planPageUrl) throws Exception {              
        GetMethod planPage = new GetMethod("http://www.e-kvytok.com.ua" + planPageUrl);
        httpClient.executeMethod(planPage);

        Document planPageDocument = new DOMReader().read(tidy.parseDOM(planPage.getResponseBodyAsStream(), null));
                     
        Element selectForm = (Element) planPageDocument.selectNodes("//form").get(1);       
        clickOnFormUrl = selectForm.attribute("action").getValue();
        
        selectLocation(clickOnFormUrl, 1);
        selectLocation(clickOnFormUrl, 2);
        
        clickOnFormUrl += "?PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.EditFormTAG0="+departure;        
        clickOnFormUrl += "&PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.EditFormTAG1="+destination;
        clickOnFormUrl += "&PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.Submit=%D0%9D%D0%B0%D1%8F%D0%B2%D0%BD%D1%96%D1%81%D1%82%D1%8C+%D0%BC%D1%96%D1%81%D1%86%D1%8C";
        clickOnFormUrl += "&PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.EditFormTAG2="+date;
        clickOnFormUrl += "&PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.EditFormTAG5=";
        clickOnFormUrl += "&PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.EditFormTAG6=";        

        PostMethod resultsPage = new PostMethod("http://www.e-kvytok.com.ua" + clickOnFormUrl);
        httpClient.executeMethod(resultsPage);
        
        Document resultsDocument = new DOMReader().read(tidy.parseDOM(resultsPage.getResponseBodyAsStream(), null));
        
        Element trainTable = (Element) resultsDocument.selectSingleNode("//table[tr/th//text()[contains(., \"Маршрут поїзда\")]]");        
		List<Node> rows = trainTable.elements();
        for (Node row : rows) {
        	List<Node> cells = ((Element)row).elements();
        	for (Node cell : cells)
        		System.out.print(cell.getStringValue() + " ");
        	System.out.println();
        }
    }

    // Вибір місця відправлення і прибуття
    private void selectLocation(String selectUrl, int locationNumber) throws Exception {
        String url = "http://www.e-kvytok.com.ua" + selectUrl;      
        url += "?PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.EditFormTAG0="+departure;        
        url += "&PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.EditFormTAG1="+destination;
        url += "&PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.SubmitSp"+locationNumber+"=%D0%97%D0%BD%D0%B0%D0%B9%D1%82%D0%B8+%D1%81%D1%82%D0%B0%D0%BD%D1%86%D1%96%D1%8E";
        url += "&PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.EditFormTAG2="+date;
        url += "&PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.EditFormTAG5=";
        url += "&PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.EditFormTAG6=";        

        PostMethod selectPage = new PostMethod(url);
        
        httpClient.executeMethod(selectPage);
        
        Document doc = new DOMReader().read(tidy.parseDOM(selectPage.getResponseBodyAsStream(), null));
        
        Element confirmLocationForm = (Element) doc.selectNodes("//form").get(1);
        String confirmLocationUrl = confirmLocationForm.attribute("action").getValue();
        
        Element locationCodeList = (Element) confirmLocationForm.selectSingleNode("//select[@name=\"PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.SelFormSp\"]/option");
        String locationCode = locationCodeList.attribute("value").getValue();
        
        String confirmPageUrl = "http://www.e-kvytok.com.ua" + confirmLocationUrl;
        confirmPageUrl += "?PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.EditFormTAG0="+departure;        
        confirmPageUrl += "&PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.EditFormTAG1="+destination;
        confirmPageUrl += "&PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.EditFormTAG2="+date;
        confirmPageUrl += "&PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.EditFormTAG5=";
        confirmPageUrl += "&PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.EditFormTAG6=";
        confirmPageUrl += "&PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.SelFormSp="+URLEncoder.encode(locationCode, "UTF-8");
        confirmPageUrl += "&PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.SubmitSpSelect=%D0%92%D0%B8%D0%B1%D1%80%D0%B0%D1%82%D0%B8+%D1%81%D1%82%D0%B0%D0%BD%D1%86%D1%96%D1%8E";

        PostMethod confirmedPage = new PostMethod(confirmPageUrl);        
        httpClient.executeMethod(confirmedPage);
        
        Document confirmedDoc = new DOMReader().read(tidy.parseDOM(confirmedPage.getResponseBodyAsStream(), null));
        
        Element updatedValueElement = (Element) confirmedDoc.selectSingleNode("//input[@name=\"PC_7_91HG12828OVIB02FV7TUIS20G0000000_rezervation.EditFormTAG" + (locationNumber-1) +"\"]");
        String updatedValue = URLEncoder.encode(updatedValueElement.attribute("value").getValue(),"UTF-8");
        
        if (locationNumber == 1) departure = updatedValue;
        if (locationNumber == 2) destination = updatedValue;
        
        Element selectForm = (Element) confirmedDoc.selectNodes("//form").get(1);       
        clickOnFormUrl = selectForm.attribute("action").getValue();
    }
}
